package com.example.design.leetcode.StackAndQueue;

//剑指 Offer 59 - II. 队列的最大值 - 解决方案

//请定义一个队列并实现函数 max_value 得到队列里的最大值，要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
//
//    若队列为空，pop_front 和 max_value需要返回 -1
//
//    示例 1：
//    输入:
//    ["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
//    [[],[1],[2],[],[],[]]
//    输出:[null,null,null,2,1,2]
//
//    示例 2：
//    输入:
//    ["MaxQueue","pop_front","max_value"]
//    [[],[],[]]
//    输出:[null,-1,-1]
//
//    限制：
//    1 <= push_back,pop_front,max_value的总操作数<= 10000
//    1 <= value <= 10^5

import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class Practice23 {
    Queue<Integer> queue;
    Deque<Integer> deque;

    public Practice23() {
        queue = new LinkedList<>();
        deque = new LinkedList<>();
    }

    public int max_value() {
        if (deque.isEmpty()) {
            return -1;
        }

        // 辅助队列是递减的，第一个元素一定是最大值
        return deque.peekFirst();
    }

    public void push_back(int value) {
        queue.add(value);

        // 保持辅助队列递减
        while(!deque.isEmpty() && deque.peekLast() < value) {
            deque.removeLast();
        }
        deque.addLast(value);
    }

    public int pop_front() {
        if (queue.isEmpty()) {
            return -1;
        }

        Integer poll = queue.poll();

        // 移出的值恰好等于辅助队列的头元素，辅助队列也需要移出元素
        if (poll.equals(deque.peekFirst())) {
            deque.removeFirst();
        }

        return poll;
    }
}
